<?php
/*
 * Author  : top-songshijie
 * Email   : 997031758@qq.com
 * DateTime: 2023/03/23 09:47
 */

namespace SSJ\LaravelHelper\Services\Sms;

use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Cache;
use SSJ\LaravelHelper\Jobs\SendSmsJob;
use SSJ\LaravelHelper\Exceptions\UnprocessableEntityException;

class SmsService
{
    /**
     * 发送短信验证码
     *
     * @param string $mobile
     *
     * @return array
     * @throws UnprocessableEntityException
     */
    public function send($mobile, $asyn)
    {
        $limit_second = 30;
        $limit_key    = 'sms_' . $mobile;
        if (Cache::get($limit_key)) {
            throw new UnprocessableEntityException($limit_second . '秒内限发送一次短信');
        }
        Cache::put($limit_key, 1, Carbon::now()->addSeconds($limit_second));
        if (config('laravel-helper.sms.debug')) {
            $verify_code = 1234;
        } else {
            $verify_code = random_int(1000, 9999);
        }

        /* laravel版本小于6的情况 */
        if (lh_laravel_version() < '6') {
            SendSmsJob::dispatch(['mobile' => $mobile, 'verify_code' => $verify_code]);
        }

        /* 其他情况 */
        if ($asyn) {
            SendSmsJob::dispatch(['mobile' => $mobile, 'verify_code' => $verify_code]);
        } else {
            SendSmsJob::dispatchSync(['mobile' => $mobile, 'verify_code' => $verify_code]);
        }

        $verify_key = 'verify_key_' . Str::random(15);
        Cache::put($verify_key, ['mobile' => $mobile, 'verify_code' => $verify_code], Carbon::now()->addMinutes(5));

        return ['verify_key' => $verify_key];
    }

    /**
     * 验证验证码是否正确
     *
     * @param string $mobile
     * @param string $verify_key
     * @param string $verify_code
     * @param bool   $is_destroy
     *
     * @return bool
     * @throws UnprocessableEntityException
     */
    public function verify($mobile, $verify_key, $verify_code, $is_destroy)
    {
        $verify_data = Cache::get($verify_key);

        if (!$verify_data) {
            throw new UnprocessableEntityException('验证码已失效,请重新获取');
        }

        if ($verify_data['mobile'] != $mobile) {
            throw new UnprocessableEntityException('两次输入手机号不一致');
        }

        if (!hash_equals((string)$verify_data['verify_code'], (string)$verify_code)) {
            throw new UnprocessableEntityException('验证码错误,请重新获取');
        }

        if ($is_destroy) {
            Cache::forget($verify_key);
        }

        return true;
    }
}